#! /usr/bin/env ruby

=begin
  GLExcess v1.0 Demo
  Copyright (C) 2001-2003 Paolo Martella
  
  This program is free software; you can redistribute it and/or
  modify it under the terms of the GNU General Public License
  as published by the Free Software Foundation; either version 2
  of the License, or (at your option) any later version.
  
  This program is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  GNU General Public License for more details.

* Original code : Paolo Martella
* Ruby Porting  : vaiorabbit  <http://twitter.com/vaiorabbit>
=end

require 'optparse'

require 'opengl'
require 'texture'

require 'scene01'
require 'scene02'
require 'scene03'
require 'scene04'
require 'scene05'
require 'scene06'
require 'scene07'
require 'scene08'
require 'scene09'
require 'scene10'
require 'scene11'
require 'scene12'

class GLExcess

  def next_scene
    if @scene != nil
      @scene.clean
      @scene = nil
      GC.start
      @timing = 0
      @step   = 1.0
      @current_scene += 1
      @current_scene %= 12
      @scene = @scenes[@current_scene].new
      glutSetWindowTitle( "GLExcess/Ruby : " + @scene.class.to_s )
    end
  end

  def prev_scene
    if @scene != nil
      @scene.clean
      @scene = nil
      GC.start
      @timing = 0
      @step   = 1.0
      @current_scene -= 1
      @current_scene %= 12
      @scene = @scenes[@current_scene].new
      glutSetWindowTitle( "GLExcess/Ruby : " + @scene.class.to_s )
    end
  end

  def draw
    if @run
      if !@scene.render( @timing )
        next_scene()
      end
      @timing += @step
    end

    glutSwapBuffers()
  end


  def idle
    glutPostRedisplay()
  end


  def key( key, x, y )
    case key
    when ?a
      @step += 1
    when ?z
      @step = [-1, @step-1].max
    when ?s
      # Suspend/Resume
      @run = !@run
    when ?n
      # Next Scene
      next_scene()
    when ?p
      # Previous Scene
      prev_scene()
    when ?\e, ?q
      # 'Esc' or 'q' : Quit program.
      exit
    end
  end


  def special( key, x, y )
    case key
    when GLUT_KEY_UP

    when GLUT_KEY_DOWN

    when GLUT_KEY_LEFT

    when GLUT_KEY_RIGHT

    end
    glutPostRedisplay()
  end


  def reshape( width, height )
    @window_width  = width
    @window_height = height

    glViewport( 0, 0, @window_width, @window_height )

    glMatrixMode( GL_PROJECTION )
    glLoadIdentity
    GLU.Perspective( 45.0, @window_width.to_f/@window_height.to_f, 0.1, 110.0 )

    glMatrixMode( GL_MODELVIEW )
    glLoadIdentity

    @scene.render( @timing )

    glutPostRedisplay()
  end


  def visible( vis )
    glutIdleFunc( ( vis == GLUT_VISIBLE ? method(:idle).to_proc : nil ) )
  end


  def mouse( button, state, x, y )
  end


  def motion( x, y )
  end


  def initialize
    # Parse Option
    scene = 1
    ARGV.options do |opt|
      opt.on( '-s', '--scene : # of Scene [1-12]', Integer, /1[0-2]|[1-9]/ ) { |v| scene = v.to_i }
      opt.parse!
    end

    @current_scene = scene - 1

    @scenes = [ Scene01, Scene02, Scene03, Scene04, Scene05, Scene06,
                 Scene07, Scene08, Scene09, Scene10, Scene11, Scene12 ]


    @window_width  = 640
    @window_height = 480

    glutInit()

    glutInitDisplayMode( GLUT_RGBA | GLUT_DEPTH | GLUT_DOUBLE )
    glutInitWindowPosition( 0, 0 )
    glutInitWindowSize( @window_width, @window_height )
    @window = glutCreateWindow()

    glutDisplayFunc     method(:draw).to_proc
    glutReshapeFunc     method(:reshape).to_proc
    glutKeyboardFunc    method(:key).to_proc
    glutSpecialFunc     method(:special).to_proc
    glutVisibilityFunc  method(:visible).to_proc
    glutMouseFunc       method(:mouse).to_proc
    glutMotionFunc      method(:motion).to_proc

    @timing = 0.0
    @step   = 1.0

    @run = true

    @scene = @scenes[@current_scene].new
    glutSetWindowTitle( "GLExcess/Ruby : " + @scene.class.to_s )
  end

  def start
    glutMainLoop()
  end

  def destroy
    glutDestroyWindow( @window )
  end

end


app = GLExcess.new
begin
  app.start
ensure
  app.destroy
end
